use eframe::egui::{self, TextStyle, Ui};
use std::collections::HashSet;

#[derive(PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
enum DemoType {
    Manual,
    ManyHomogeneous,
    ManyHeterogenous,
}

#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct TableSymbol {
    demo: DemoType,
    striped: bool,
    resizable: bool,
    clickable: bool,
    num_rows: usize,
    scroll_to_row_slider: usize,
    scroll_to_row: Option<usize>,
    selection: HashSet<usize>,
    checked: bool,
}

impl Default for TableSymbol {
    fn default() -> Self {
        Self {
            demo: DemoType::Manual,
            striped: true,
            resizable: true,
            clickable: true,
            num_rows: 10_000,
            scroll_to_row_slider: 0,
            scroll_to_row: None,
            selection: Default::default(),
            checked: false,
        }
    }
}

impl TableSymbol {
    pub fn new() -> Self {
        Self::default()
    }

    pub fn show(&mut self, ui: &mut Ui) {
        ui.group(|ui| {
            let mut reset = false;

            let body_text_size = TextStyle::Body.resolve(ui.style()).size;
            use egui_extras::{Size, StripBuilder};
            StripBuilder::new(ui)
                .size(Size::remainder().at_least(100.0).at_most(200.0))
                .size(Size::exact(body_text_size))
                .vertical(|mut strip| {
                    strip.cell(|ui| {
                        egui::ScrollArea::horizontal().show(ui, |ui| {
                            self.table_ui(ui, reset);
                        });
                    });
                    strip.cell(|ui| {
                        ui.vertical_centered(|ui| {
                            // ui.add(
                            //     egui::Hyperlink::new("https://github.com/emilk/egui")
                            //         .text("egui on GitHub"),
                            // );
                        });
                    });
                });
        });
    }

    fn table_ui(&mut self, ui: &mut egui::Ui, reset: bool) {
        use egui_extras::{Column, TableBuilder};

        let text_height = TextStyle::Body
            .resolve(ui.style())
            .size
            .max(ui.spacing().interact_size.y);

        let available_height = ui.available_height();
        let mut table = TableBuilder::new(ui)
            .striped(self.striped)
            .resizable(self.resizable)
            .cell_layout(egui::Layout::left_to_right(egui::Align::Center))
            .column(Column::auto())
            .column(
                Column::remainder()
                    .at_least(40.0)
                    .clip(true)
                    .resizable(true),
            )
            .column(Column::auto())
            .column(Column::remainder())
            .min_scrolled_height(0.0)
            .max_scroll_height(available_height);

        if self.clickable {
            table = table.sense(egui::Sense::click());
        }

        if let Some(row_index) = self.scroll_to_row.take() {
            table = table.scroll_to_row(row_index, None);
        }

        if reset {
            table.reset();
        }

        table
            .header(20.0, |mut header| {
                header.col(|ui| {
                    ui.strong("交易品种");
                });
                header.col(|ui| {
                    ui.strong("卖价");
                });
                header.col(|ui| {
                    ui.strong("买价");
                });
                header.col(|ui| {
                    ui.strong("涨跌百分比");
                });
            })
            .body(|mut body| match self.demo {
                DemoType::Manual => {
                    for row_index in 0..5 {
                        body.row(18.0, |mut row| {
                            row.set_selected(self.selection.contains(&row_index));

                            row.col(|ui| {
                                ui.label(format!("EURUSD"));
                            });
                            row.col(|ui| {
                                ui.label(format!("1.08839"));
                            });
                            row.col(|ui| {
                                ui.label(format!("1.08877"));
                            });
                            row.col(|ui| {
                                ui.label(format!("-0.11%"));
                            });

                            self.toggle_row_selection(row_index, &row.response());
                        });
                    }
                }
                DemoType::ManyHomogeneous => {
                    body.rows(text_height, self.num_rows, |mut row| {
                        let row_index = row.index();
                        row.set_selected(self.selection.contains(&row_index));

                        row.col(|ui| {
                            ui.label(format!("EURUSD"));
                        });
                        row.col(|ui| {
                            ui.label(format!("1.08839"));
                        });
                        row.col(|ui| {
                            ui.label(format!("1.08877"));
                        });
                        row.col(|ui| {
                            ui.label(format!("-0.11%"));
                        });

                        self.toggle_row_selection(row_index, &row.response());
                    });
                }
                DemoType::ManyHeterogenous => {
                    body.heterogeneous_rows((0..self.num_rows).map(|_| 18.0), |mut row| {
                        let row_index = row.index();
                        row.set_selected(self.selection.contains(&row_index));

                        row.col(|ui| {
                            ui.label(format!("EURUSD"));
                        });
                        row.col(|ui| {
                            ui.label(format!("1.08839"));
                        });
                        row.col(|ui| {
                            ui.label(format!("1.08877"));
                        });
                        row.col(|ui| {
                            ui.label(format!("-0.11%"));
                        });

                        self.toggle_row_selection(row_index, &row.response());
                    });
                }
            });
    }

    fn toggle_row_selection(&mut self, row_index: usize, row_response: &egui::Response) {
        if row_response.clicked() {
            if self.selection.contains(&row_index) {
                self.selection.remove(&row_index);
            } else {
                // self.selection.insert(&row_index);
            }
        }
    }
}
